package com.chengliang0315.locationtest.util.location;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.telephony.TelephonyManager;
import android.telephony.cdma.CdmaCellLocation;
import android.telephony.gsm.GsmCellLocation;
import android.widget.Toast;

import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.chengliang0315.locationtest.util.LogUtils;

import org.json.JSONException;
import org.json.JSONObject;


/**
 * LBS（Location Based Service）基站定位
 *
 * @author chengliang0315
 * @see <a>http://blog.csdn.net/chengliang0315</a>
 */
public class LBSLocation {

    private static LBSLocation instance;
    private static Context mContext;

    private static OnLBSLocationRequestListener listener;

    public static LBSLocation getInstance(Context mContext, OnLBSLocationRequestListener listener) {
        if (instance == null) {
            instance = new LBSLocation(mContext, listener);
        }
        return instance;
    }

    private LBSLocation(Context mContext, OnLBSLocationRequestListener listener) {
        this.mContext = mContext;
        this.listener = listener;
    }

    /**
     * 通过此方法请求定位信息
     */
    public void request() {
        String url = "http://api.cellocation.com/cell/?mcc=%1$s&mnc=%2$s&lac=%3$s&ci=%4$s&output=json";

        StationInfo info = getCellInfo();

        if (info == null) {
            listener.onFailed();
            return;
        }
        LogUtils.i(info.toString());
        url = String.format(url, info.getMCC(), info.getMNC(), info.getLAC(), info.getCID());
        //通过网络请求获取经纬度和详细位置
        getLocation(url);
    }

    /**
     * 获取基站信息
     */
    private StationInfo getCellInfo() {
        StationInfo stationInfo = new StationInfo();
        LogUtils.e(ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION)
                + "====" + ActivityCompat.checkSelfPermission(mContext,
                Manifest.permission.ACCESS_COARSE_LOCATION) + "");
        if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext,
                Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            return null;
        }

        /** 调用API获取基站信息 */
        TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);

        if (!hasSimCard(mContext)) { //判断有没有sim卡
            Toast.makeText(mContext, "请安装sim卡", Toast.LENGTH_LONG).show();
            return null;
        }
        String operator = telephonyManager.getNetworkOperator();
        LogUtils.e("operator", "operator=" + operator);
        int mcc = Integer.parseInt(operator.substring(0, 3));
        int mnc = Integer.parseInt(operator.substring(3));

        //参考http://www.cellocation.com/interfac/
        LogUtils.e("mnc", "mnc=" + mnc);
        int cid = 0;
        int lac = 0;
        if (mnc == 11 || mnc == 03 || mnc == 05) {  //03 11
            CdmaCellLocation location = (CdmaCellLocation) telephonyManager.getCellLocation();
            LogUtils.e("基站识别码：" + location.getBaseStationId() + "  经度：" + location.getBaseStationLongitude() + "  纬度：" + location.getBaseStationLatitude());
            cid = location.getBaseStationId();
            lac = location.getNetworkId();
            mnc = location.getSystemId();
        } else {
            GsmCellLocation location = (GsmCellLocation) telephonyManager.getCellLocation();
            cid = location.getCid();
            lac = location.getLac();
        }

        /** 将获得的数据放到结构体中 */
        stationInfo.setMCC(mcc);
        stationInfo.setMNC(mnc);
        stationInfo.setLAC(lac);
        stationInfo.setCID(cid);

        return stationInfo;
    }


    /**
     * 通过网络请求获取地理位置
     */
    private void getLocation(String url) {

        LogUtils.i(url);
        StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                LogUtils.json(response);
                LocationInfo info = new LocationInfo();
                try {
                    JSONObject body = new JSONObject(response);
                    info.setAddress(body.getString("address"));
                    info.setLongitude(body.getDouble("lon"));
                    info.setLatitude(body.getDouble("lat"));
                    listener.onSucceed(info);
                } catch (JSONException e) {
                    e.printStackTrace();
                    listener.onFailed();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                listener.onFailed();
            }
        });
        Volley.newRequestQueue(mContext).add(request);
    }

    /**
     * 判断是否安装SIM卡
     *
     * @return 状态
     */
    public static boolean hasSimCard(Context context) {
        TelephonyManager telephonyManager = (TelephonyManager)
                context.getSystemService(Context.TELEPHONY_SERVICE);
        int simState = telephonyManager.getSimState();
        boolean result = true;
        switch (simState) {
            case TelephonyManager.SIM_STATE_ABSENT:
                result = false; // 没有SIM卡
                break;
            case TelephonyManager.SIM_STATE_UNKNOWN:
                result = false;
                break;
        }
        LogUtils.i(result ? "有SIM卡" : "无SIM卡");
        return result;
    }

    /**
     * 请求lbs定位回调接口
     */
    public interface OnLBSLocationRequestListener {
        /**
         * 请求成功
         */
        void onSucceed(LocationInfo response);

        /**
         * 请求失败
         */
        void onFailed();
    }

    /**
     * 基站信息
     * MCC: 国家代码：中国代码 460
     * MNC，移动设备网络代码（Mobile Network Code，MNC），中国移动 = 00，中国联通 = 01, 中国电信 = 03 05 11
     * LAC，Location Area Code，位置区域码；
     * CID，Cell Identity，基站编号，是个16位的数据（范围是0到65535）。
     */
    public static class StationInfo {
        private int MCC;
        private int MNC;
        private int LAC;
        private int CID;

        public int getMCC() {
            return MCC;
        }

        public void setMCC(int MCC) {
            this.MCC = MCC;
        }

        public int getMNC() {
            return MNC;
        }

        public void setMNC(int MNC) {
            this.MNC = MNC;
        }

        public int getLAC() {
            return LAC;
        }

        public void setLAC(int LAC) {
            this.LAC = LAC;
        }

        public int getCID() {
            return CID;
        }

        public void setCID(int CID) {
            this.CID = CID;
        }

        @Override
        public String toString() {
            return "StationInfo{" +
                    "MCC=" + MCC +
                    ", MNC=" + MNC +
                    ", LAC=" + LAC +
                    ", CID=" + CID +
                    '}';
        }
    }

}
